Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(auth): Add /userinfo endpoint for OIDC #52493

Merged
merged 6 commits into from
Jul 11, 2023

Conversation

EricHasegawa
Copy link
Contributor

Implements the /userinfo endpoint for OIDC compliance (initial spec is here).

Note that anyone can call this endpoint - the authentication/authorization comes from the bearer token they pass in.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Jul 8, 2023
@codecov
Copy link

codecov bot commented Jul 8, 2023

Codecov Report

Merging #52493 (ec7a2b7) into master (66fccaf) will decrease coverage by 1.61%.
The diff coverage is 100.00%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #52493      +/-   ##
==========================================
- Coverage   79.35%   77.74%   -1.61%     
==========================================
  Files        4914     4893      -21     
  Lines      206216   206110     -106     
  Branches    35250    35247       -3     
==========================================
- Hits       163634   160249    -3385     
- Misses      37569    40708    +3139     
- Partials     5013     5153     +140     
Impacted Files Coverage Δ
src/sentry/api/endpoints/oauth_userinfo.py 100.00% <100.00%> (ø)
src/sentry/web/urls.py 92.30% <100.00%> (+0.12%) ⬆️

... and 338 files with indirect coverage changes

Copy link
Member

@cathteng cathteng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't have much context so just some general questions

src/sentry/api/endpoints/oauth_userinfo.py Show resolved Hide resolved
src/sentry/api/endpoints/oauth_userinfo.py Outdated Show resolved Hide resolved
src/sentry/api/endpoints/oauth_userinfo.py Show resolved Hide resolved
@cathteng cathteng requested a review from a team July 10, 2023 16:21
Copy link
Contributor

@nhsiehgit nhsiehgit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick comment

src/sentry/api/urls.py Outdated Show resolved Hide resolved
@EricHasegawa EricHasegawa force-pushed the EricHasegawa/add-oidc-to-token-endpoint branch from dc5ceec to 1775f42 Compare July 10, 2023 20:03
@EricHasegawa EricHasegawa requested a review from a team as a July 10, 2023 20:03
@EricHasegawa EricHasegawa force-pushed the EricHasegawa/add-oidc-to-token-endpoint branch from a2bcaf9 to 932084f Compare July 10, 2023 20:27
Base automatically changed from EricHasegawa/add-oidc-to-token-endpoint to master July 10, 2023 21:32
Copy link
Contributor

@nhsiehgit nhsiehgit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

non blocking comment.
Up to your discretion

src/sentry/api/urls.py Outdated Show resolved Hide resolved
src/sentry/api/endpoints/oauth_userinfo.py Outdated Show resolved Hide resolved
src/sentry/api/endpoints/oauth_userinfo.py Outdated Show resolved Hide resolved
src/sentry/api/endpoints/oauth_userinfo.py Outdated Show resolved Hide resolved
Comment on lines +32 to +35
"name": user.name,
"avatar_type": user.avatar_type,
"avatar_url": user.avatar_url,
"date_joined": user.date_joined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally our API outputs properties with camelBacked identifiers. Is there a reason to diverge from that convention here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah - the OAuth/OIDC requires snake case in order for this to be considered a valid implementation - here's a thread discussing this exact thing.

However - this is only for the required OAuth stuff like client_id, access_token etc. So technically we could return those in snake case, and return the custom userinfo stuff in camelCase, but, I figured that would be even more confusing. LMK if you prefer it that way though and I can change it over!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point about the OIDC spec having standards for response keys. 🤔 Having two conventions in the same response is clunky. Lets go forward with what you have. Having consistency within the response which needs to follow the standard for some properties seems more important than our local API response key conventions.

user_output.update(profile_details)
if "email" in scopes:
email = UserEmail.objects.get(user=user)
email_details = {"email": email.email, "email_verified": email.is_verified}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The email_verified attribute is generally serialized as is_verified. While It is unfortunately a snake cased identifier we should try to use consistent names across various endpoints.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I named this one email_verified since it's consistent with standard OIDC language (example from Auth0).

Also - this response contains more details on the user than just email stuff, if we just have is_verified do you think clients might be unsure as to what exactly is verified?

On the other hand, maybe is_verified, by extension, implies that the user is verified, and not just the email, plus we would be consistent with our codebase, rather than the OAuth standards, so there's a trade-off here.

I'd leave it this way but I'm good either way - lmk if you want me to change it over still and I will!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points. Combined with the OIDC conventions discussed above, let's leave this as you have it.

tests/sentry/api/endpoints/test_oauth_userinfo.py Outdated Show resolved Hide resolved
@EricHasegawa EricHasegawa requested a review from markstory July 11, 2023 17:18
Comment on lines +32 to +35
"name": user.name,
"avatar_type": user.avatar_type,
"avatar_url": user.avatar_url,
"date_joined": user.date_joined,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point about the OIDC spec having standards for response keys. 🤔 Having two conventions in the same response is clunky. Lets go forward with what you have. Having consistency within the response which needs to follow the standard for some properties seems more important than our local API response key conventions.

user_output.update(profile_details)
if "email" in scopes:
email = UserEmail.objects.get(user=user)
email_details = {"email": email.email, "email_verified": email.is_verified}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points. Combined with the OIDC conventions discussed above, let's leave this as you have it.

@EricHasegawa EricHasegawa merged commit 8839b6d into master Jul 11, 2023
@EricHasegawa EricHasegawa deleted the EricHasegawa/create-userinfo branch July 11, 2023 22:12
@github-actions github-actions bot locked and limited conversation to collaborators Jul 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Scope: Backend Automatically applied to PRs that change backend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants